<script>
import BMF from 'browser-md5-file';
import { deleteVideo, getOssfiles, mediaPartUpload, mediaUpload, updateVideo } from '@/api/user';
import { getVideoTimes } from '@/utils/utilsNew';
import { videoTimeList } from '@/config/house/houseDetailConfig';

/** 分割上传的单位大小 */
const UNIT_SIZE = 5 * 1024 * 1024;
/** 视频最大大小 */
const MAX_SIZE = 300 * 1024 * 1024;
/** 支持的视频格式 */
const VIDEO_TYPE_LIST = ['avi', 'mov', 'mp4'];

const bmf = new BMF();
const debugNotMerge = false;
export default {
  components: {},
  props: {
    hmDelSummaryInfo: {
      type: Object,
      default() {
        return {};
      },
    },
    room: {
      type: String | Number,
      default: '1',
    },
    houDelId: {
      type: String,
      default: '',
    },
  },
  data() {
    return {
      loading: false,
      loadText: '加载中',
      houseImages: [
        { playUrl: '', },
      ],
    };
  },
  render() {
    const { loading, loadText, houseImages, handleUploadVideo, handleDeleteVideo, handleVrToVideo } = this;
    return (
      <div>
        <input class="input-upload" ref="videoInput" type="file" title="选择视频文件" onChange={this.handleUpload} />
        {this.$scopedSlots.default({
          loading,
          loadText,
          houseImages,
          handleUploadVideo,
          handleDeleteVideo,
          handleVrToVideo,
        })}
      </div>
    );
  },
  watch: {
    hmDelSummaryInfo: {
      handler(newValue = {}, oldValue = {}) {
        if (!newValue.videoMaterial || !newValue.videoMaterial.videoId) return;

        let newId = newValue.videoMaterial.videoId;
        if (oldValue.videoMaterial && oldValue.videoMaterial.videoId && oldValue.videoMaterial.videoId == newId) return;
        getOssfiles(newId).then(({ data }) => {
          this.updatePlayUrl(data, newId);

          getVideoTimes(data).then((time) => {
            this.$emit('onvideoupdate', time);
          });
        });
      },
      deep: true,
      immediate: true,
    },
  },
  mounted() {},
  methods: {
    handleVrToVideo() {
      const { videoStatus, houSubTypeState } = this.hmDelSummaryInfo;
      if (videoStatus == '1') {
        return this.$message.error('视频正在合成中，稍后再试～');
      }
      if (houSubTypeState == '1') {
        return this.$message.error('VR正在下载中，请等待VR下载完后使用～');
      }

      this.vrToVideoHandler(this.houDelId);
    },

    vrToVideoHandler(delId) {
      this.$router.push({
        name: 'vrTurnVideo',
        params: { houDelId: delId, required: '0' },
      });
    },

    handleDeleteVideo() {
      this.$messageBox.confirm('确认删除视频？', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
      }).then(() => {
        deleteVideo({ delId: this.houDelId }).then(() => {
          this.houseImages = [{ playUrl: '', }]
          this.$emit('ondelete');
        });
      }).catch(()=>{})
    },

    handleLoadedmetadata(e) {
      // console.log("视频监听加载事件", this.$refs.videoDom );
    },
    updatePlayUrl(url, id) {
      this.houseImages[0].playUrl = url;
    },

    handleUploadVideo() {
      if (this.hmDelSummaryInfo.videoStatus == 1) {
        this.$message.error('您当前有正在合成中的视频！');
        return;
      }
      if (this.room == '0' || !this.room) {
        return this.$message.error(`暂未填写户型！`);
      }
      if (this.houseImages[0].playUrl) {
        this.$messageBox.confirm('重新上传视频会替换现有视频，是否继续？').then(() => {
          this.$refs.videoInput.click();
        });
      } else {
        this.$refs.videoInput.click();
      }
    },

    async handleUpload() {
      let file = this.$refs.videoInput.files[0];

      // console.log("文件== ", file);

      if (file.size > MAX_SIZE) {
        this.$message.error('不可超过视频文件上限300M！');
        return;
      }
      let fileType = file.type.split('/')[1];
      if (!VIDEO_TYPE_LIST.includes(fileType.toLocaleLowerCase())) {
        this.$message.error(`仅支持${VIDEO_TYPE_LIST.join('、')}格式的视频！`);
        return;
      }

      let time = await getVideoTimes(file);
      // return console.log("时长=== ", time);

      let minTime = videoTimeList[this.room] || Math.max.apply(null, Object.values(videoTimeList));
      if (time < minTime) {
        this.$message.error(`${this.room}室户上传视频不得小于${minTime}秒`);
        return;
      }

      this.loading = true;
      this.loadText = '正在编码视频文件 0%';

      let hash = await this.getMd5(file, (process) => {
        // console.log('md5== ', process);
        this.loadText = `正在编码视频文件 ${Math.floor(process * 100)}%`;
      });
      let fileList = this.sliceFileList(file);
      let hashList = await this.getPartHashs(fileList, (process) => {
        let point = Math.floor(((process + 1) / fileList.length) * 100);
        this.loadText = `正在切割视频文件 ${point}%`;
      });

      // 调试md5计算速度
      // return;

      this.loadText = '正在上传视频 0%';

      let { code, content, memo } = await mediaUpload({
        action: 'upload_slice',
        fileType,
        hash,
        fileName: file.name,
        partHashs: hashList,
      });

      if (code == '000000') {
        let id = content.id;
        // 表示服务端已有该视频
        if (content.playUrl) {
          this.$message.success('上传成功！');
          this.updatePlayUrl(content.playUrl, id);
          this.submitVideoUpdate(id);
          this.$emit('onvideoupdate', time);
          this.$emit('onsuccess');

          this.loading = false;
        } else {
          let startIndex = content.part ? content.part : 1;
          this.startMediaPartUpload(id, fileList, hashList, startIndex)
            .then(({ id, playUrl }) => {
              this.updatePlayUrl(playUrl, id);
              this.submitVideoUpdate(id);
              this.$emit('onvideoupdate', time);
              this.$emit('onsuccess');
            })
            .finally(() => {
              this.loading = false;
            });
        }
      } else {
        this.$message.error(memo);
        this.loading = false;
      }
    },

    getMd5(blob, progressFn) {
      return new Promise((resolve, reject) => {
        let start = Date.now();
        bmf.md5(
          blob,
          (err, md5) => {
            if (err) {
              console.log(err);
            }
            // console.log("md5 time ", md5, Date.now() - start);
            resolve(md5);
          },
          progressFn
        );
      });
    },

    sliceFileList(file) {
      let totalSize = file.size;
      let len = Math.ceil(totalSize / UNIT_SIZE);
      let arr = [];
      for (let i = 0; i < len; i++) {
        let item = file.slice(i * UNIT_SIZE, (i + 1) * UNIT_SIZE);
        arr.push(item);
      }

      return arr;
    },

    async getPartHashs(list, processFn) {
      let arr = [];
      for (let i = 0; i < list.length; i++) {
        processFn && processFn(i);
        let hash = await this.getMd5(list[i]);
        arr.push(hash);
      }

      return Promise.resolve(arr);
    },

    /**
     * id
     * fileList 文件分片后的列表
     * hashList 文件分片后对应的md5值列表
     * startIndex 在上一次上传的起点 继续上传 默认第一段
     */
    async startMediaPartUpload(id, fileList, hashList, startIndex = 1) {
      let point = Math.floor(((startIndex - 1) / fileList.length) * 100);
      this.loadText = `正在上传视频 ${point}%`;

      // 上传
      for (let i = startIndex - 1; i < fileList.length; i++) {
        const item = fileList[i];
        let formData = new FormData();
        formData.append('id', id);
        formData.append('option', 'slice');
        formData.append('hash', hashList[i]);
        formData.append('part', i + 1);
        formData.append('file', item);

        let { code, memo, content } = await mediaPartUpload(formData);
        let point = Math.floor(((i + 1) / fileList.length) * 100);
        this.loadText = `正在上传视频 ${point}%`;

        if (code == '000000') {
          // this.$message.success(`上传ok ${content.part}`);
        } else {
          this.$message.error(memo);

          return Promise.reject('上传失败了');
        }
      }

      // 暂时不上传
      if (debugNotMerge) return;

      // 合成
      let formData = new FormData();
      formData.append('id', id);
      formData.append('option', 'merge');
      formData.append('hash', -1);
      formData.append('part', -1);

      this.loadText = `正在合成视频`;

      let { code, memo, content } = await mediaPartUpload(formData);
      if (code == '000000') {
        this.$message.success(`合成视频成功！`);

        return Promise.resolve({ id, playUrl: content.playUrl });
      } else {
        this.$message.error(memo);
        return Promise.reject('合成视频失败！');
      }
    },

    submitVideoUpdate(videoId) {
      return updateVideo({
        delId: this.houDelId,
        isBind: '1',
        videoId,
      }).then(({ isSuccess, errorMessage }) => {
        if (!isSuccess) {
          return this.$messageBox
            .confirm(errorMessage, {
              confirmButtonText: '我知道了',
              showCancelButton: false,
            })
            .finally(() => {
              return Promise.resolve();
            });
        }
      });
    },
  },
};
</script>

<style lang="scss" scoped>
.input-upload {
  display: none;
}
</style>
